/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.lonnesol.swing.button;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * @date 2012-3-14, 12:03:45
 *
 * @author hualun-alan <alan.zeng@lonnesol.com>
 */
public class IconButton extends JButton {

    public static final int HORIZONTAL_OFFSET = 8;
    public static final int VERTICAL_OFFSET = 3;
    public static Font font = new Font("Arial", Font.BOLD, 11);
    private static Color color0000 = new Color(250, 254, 251);
    private static Color color0100 = new Color(203, 213, 214);
    private static Color color0200 = new Color(152, 175, 190);
    private static Color color1000 = new Color(236, 233, 216);
    private static Color color1100 = new Color(193, 206, 209);
    private static Color color1200 = new Color(142, 167, 185);
    private static Color color0101 = new Color(166, 186, 202);
    private static Color color0201 = new Color(221, 231, 234);
    private static Color color1201 = new Color(232, 238, 242);
    private static Color color0102 = new Color(224, 235, 240);
    private static Color color0110 = new Color(213, 221, 222);
    private static Color color0210 = new Color(172, 191, 203);
    private static Color color0310 = new Color(148, 173, 191);
    private static Color color0011 = new Color(186, 201, 206);
    private static Color color0111 = new Color(160, 179, 193);
    private static Color color0211 = new Color(203, 207, 208);
    private static Color color0012 = new Color(136, 162, 181);
    private static Color color0112 = new Color(216, 228, 230);
    private static Color color1112 = new Color(220, 219, 216);
    private static Color color1212 = new Color(231, 227, 221);
    private static Color color1312 = new Color(227, 224, 223);
    private static Color colorLine1 = new Color(122, 157, 177);
    private static Color colorLine2 = new Color(122, 152, 175);
    private static Color colorLine3 = new Color(228, 222, 216);
    private static Color colorLine4 = new Color(242, 240, 237);
    private static Color bgNormal = new Color(251, 255, 253);
    private static Color bgRollover = new Color(166, 244, 239);
    private static Color bgPressed = new Color(155, 187, 236);
    private static Color fg = new Color(60, 95, 133);
    protected FontMetrics fm = getFontMetrics(font);

    public IconButton(String text) {
        this.setText(text);
    }

    public IconButton() {
    }

    @Override
    public void setText(String text) {
        super.setText(text);
        calculateSize();
    }

    @Override
    public void paint(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g2d.setFont(font);
        if (!model.isEnabled()) {
            paintDisabled(g2d);
        } else if (model.isPressed()) {
            paintPressed(g2d);
        } else if (model.isRollover()) {
            paintRollover(g2d);
        } else {
            paintNormal(g2d);
        }

    }

    protected void calculateSize() {
        Dimension d = new Dimension(fm.stringWidth(getText()) + HORIZONTAL_OFFSET * 2, fm.getHeight() + VERTICAL_OFFSET * 2);
        setPreferredSize(d);
        setMaximumSize(d);
        setMinimumSize(d);
    }

    private void drawPoint(Graphics2D g, Color color, int x, int y) {
        g.setColor(color);
        g.drawLine(x, y, x, y);
    }

    private void drawBackground(Graphics2D g2d, Color bg) {
        //画背景
        g2d.setColor(bg);
        g2d.fillRect(0, 0, getWidth(), getHeight());
    }

    private void drawText(Graphics2D g2d, Color fg) {
        //画字符
        g2d.setColor(fg);
        g2d.drawString(getText(), HORIZONTAL_OFFSET, fm.getAscent() + VERTICAL_OFFSET - 1);
    }

    private void drawBorder(Graphics2D g2d) {
        int _0x = getWidth() - 1;
        int _1x = getWidth() - 2;
        int _2x = getWidth() - 3;
        int _3x = getWidth() - 4;
        int _0y = getHeight() - 1;
        int _1y = getHeight() - 2;
        int _2y = getHeight() - 3;
        int _3y = getHeight() - 4;

        //画边线
        g2d.setColor(colorLine1);
        //左1
        g2d.drawLine(0, 3, 0, _3y);
        //上1
        g2d.setColor(colorLine2);
        g2d.drawLine(3, 0, _3x, 0);
        //下1
        g2d.drawLine(3, _0y, _3x, _0y);
        //右1
        g2d.drawLine(_0x, 3, _0x, _3y);
        g2d.setColor(colorLine3);
        //下2
        g2d.drawLine(3, _1y, _3x, _1y);
        g2d.setColor(colorLine4);
        //右2
        g2d.drawLine(_1x, 3, _1x, _3y);

        //横1
        drawPoint(g2d, color0000, 0, 0);
        drawPoint(g2d, color0100, 1, 0);
        drawPoint(g2d, color0200, 2, 0);
        drawPoint(g2d, color1000, _0x, 0);
        drawPoint(g2d, color1100, _1x, 0);
        drawPoint(g2d, color1200, _2x, 0);
        //横2
        drawPoint(g2d, color1100, 0, 1);
        drawPoint(g2d, color0101, 1, 1);
        drawPoint(g2d, color0201, 2, 1);
        drawPoint(g2d, color1100, _0x, 1);
        drawPoint(g2d, color0101, _1x, 1);
        drawPoint(g2d, color1201, _2x, 1);
        //横3
        drawPoint(g2d, color1200, 0, 2);
        drawPoint(g2d, color0102, 1, 2);
        drawPoint(g2d, color1200, _0x, 2);
        drawPoint(g2d, color1201, _1x, 2);
        //横6-下至上横1
        drawPoint(g2d, color0000, 0, _0y);
        drawPoint(g2d, color0110, 1, _0y);
        drawPoint(g2d, color0210, 2, _0y);
        drawPoint(g2d, color0310, 3, _0y);
        drawPoint(g2d, color1000, _0x, _0y);
        drawPoint(g2d, color1100, _1x, _0y);
        drawPoint(g2d, color1200, _2x, _0y);
        //横5-下至上横2
        drawPoint(g2d, color0011, 0, _1y);
        drawPoint(g2d, color0111, 1, _1y);
        drawPoint(g2d, color0211, 2, _1y);
        drawPoint(g2d, color0011, _0x, _1y);
        drawPoint(g2d, color0111, _1x, _1y);
        drawPoint(g2d, color0211, _2x, _1y);
        //横4-下至上横3
        drawPoint(g2d, color0012, 0, _2y);
        drawPoint(g2d, color0112, 1, _2y);
        drawPoint(g2d, color0012, _0x, _2y);
        drawPoint(g2d, color1112, _1x, _2y);
        drawPoint(g2d, color1212, _2x, _2y);
        drawPoint(g2d, color1312, _3x, _2y);
    }

    private void paintNormal(Graphics2D g2d) {
        drawBackground(g2d, bgNormal);
        drawText(g2d, fg);
        drawBorder(g2d);
    }

    private void paintPressed(Graphics2D g2d) {
        drawBackground(g2d, bgPressed);
        drawText(g2d, fg);
        drawBorder(g2d);
    }

    private void paintRollover(Graphics2D g2d) {
        drawBackground(g2d, bgRollover);
        drawText(g2d, fg);
        drawBorder(g2d);
    }

    private void paintDisabled(Graphics2D g2d) {
        drawBackground(g2d, Color.LIGHT_GRAY);
        drawText(g2d, Color.GRAY);
        drawBorder(g2d);
    }

    public static void main(String[] args) {
        JFrame jFrame = new JFrame("Button Test");
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel jPanel = new JPanel();
        final IconButton btnView = new IconButton("View");
        btnView.setEnabled(false);
        IconButton btnEdit = new IconButton("Edit");
        btnEdit.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                System.out.println("===============");
                btnView.setEnabled(!btnView.isEnabled());
                btnView.setText(btnView.isEnabled() ? "View" : "Test View");
            }
        });

        jPanel.add(btnEdit);
        jPanel.add(btnView);
        jPanel.add(new IconButton("Approve"));
        jPanel.add(new IconButton("Reject"));
        jPanel.add(new IconButton("Un-share"));
        jFrame.getContentPane().add(jPanel);
        jFrame.setSize(500, 500);
        jFrame.setLocationRelativeTo(null);
        jFrame.setVisible(true);
    }
}
